/**
 * @Author: tt-one
 *  封装请求
 */
/**
 *  1. 创建axios 实例
 *    1. 配置请求基地址
 *    2. 请求超时时间
 *  2. 请求拦截器
 *    1. 请求头携带token
 *  3.  响应拦截器
 *    1. 剥离无效数据
 *    2. 统一处理错误
 *    3. 401错误处理
 */
import { showToast } from 'vant'
import { useUserStore } from '@/stores'
import axios, { type Method } from 'axios'

import router from '@/router'

const baseURL = 'https://consult-api.itheima.net/'
const instance = axios.create({
  baseURL,
  timeout: 10000
})

// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 携带token
    const userStore = useUserStore()
    if (userStore.user?.token) {
      config.headers.Authorization = `Bearer ${userStore.user?.token}`
    }
    return config
  },
  (err) => Promise.reject(err)
)

// 响应拦截器
instance.interceptors.response.use(
  // 状态码 200
  (res) => {
    // 处理业务错误
    if (res.data?.code !== 10000) {
      showToast(res.data?.message)
      return Promise.reject(res.data)
    }
    // 返回剥离数据
    return res.data
  },
  // 状态码 不是200
  (err) => {
    // 401 的处理
    if (err.response.status === 401) {
      const userStore = useUserStore()
      /**
       *  1. 删除用户信息
       *  2. 跳转到登录页面, 获取当前的页面路径,登录成功之后返回到这个路径
       */
      userStore.delUser()
      router.push('/login?returnUrl=' + router.currentRoute.value.fullPath)
    }
    // 统一提示错误
    showToast(err.response.data.message)
    return Promise.reject(err)
  }
)

//封装请求 工具类函数
// method 不能写string  因为这样只需要传递字符串就可以了,  我们必须要规定传递method 关键字才可以
// 传递的参数需要根据method的方式来决定 (我们鼠标单击跳转进来,然后观察request 里面的参数传递,所以我们使用axios提供的类型)

// 经过测试发现
// 因为我们已经剥离数据了,但是此时给我们返回的还是 默认值给我ts的提示
// 所以我们需要修改默认值

// 修改默认提示,
// 修改第一个参数, 将第一个参数修改成动态参数, 我们要根据请求的结果来动态决定这个动态参数
// 第二个参数是一个默认值, 需要我们来修改这个默认值
type Data<T> = {
  code: number
  data: T
  message: string
}

// request 请求的这个T代表的是,当你请求返回的数据, 那个数据类型传递到这里
const request = <T>(url: string, method?: Method, submitData?: object) => {
  if (!method) method = 'GET'
  return instance.request<T, Data<T>>({
    url,
    method,
    [method === 'get' ? 'params' : 'data']: submitData
  })
}

// 将这些数据导出
export { baseURL, instance, request }
